package com.finna.tenant.controller;

import com.finna.common.utils.ResponseResult;
import com.finna.tenant.dto.*;
import com.finna.tenant.dto.AccountDTO.AccountWithTenantsResponse;
import com.finna.tenant.dto.TenantAccountJoinDTO.*;
import com.finna.tenant.service.TenantAccountJoinService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

/**
 * 租户账号关联控制器
 */
@RestController
@RequestMapping("/tenant-account-join")
@Tag(name = "租户账号关联接口", description = "租户、账号、角色三者关联管理")
public class TenantAccountJoinController {
    
    private static final Logger logger = LoggerFactory.getLogger(TenantAccountJoinController.class);
    
    @Autowired
    private TenantAccountJoinService tenantAccountJoinService;
    
    /**
     * 添加租户账号关联
     */
    @PostMapping
    @Operation(summary = "添加租户账号关联", description = "将账号关联到租户并分配角色")
    public ResponseResult<TenantAccountJoinResponse> add(
            @Validated @RequestBody TenantAccountJoinCreateRequest request) {
        try {
            TenantAccountJoinResponse response = tenantAccountJoinService.create(request);
            logger.info("添加租户账号关联成功: joinId={}", response.getId());
            return ResponseResult.success(response);
        } catch (RuntimeException e) {
            logger.error("添加租户账号关联失败: {}", e.getMessage());
            return ResponseResult.error(400, "添加失败: " + e.getMessage());
        } catch (Exception e) {
            logger.error("添加租户账号关联失败: {}", e.getMessage(), e);
            return ResponseResult.error(500, "添加失败: " + e.getMessage());
        }
    }
    
    /**
     * 更新租户账号关联
     */
    @PutMapping("/{id}")
    @Operation(summary = "更新租户账号关联", description = "更新租户账号的角色")
    public ResponseResult<TenantAccountJoinResponse> update(
            @Parameter(description = "关联ID") @PathVariable Long id,
            @RequestBody TenantAccountJoinUpdateRequest request) {
        try {
            TenantAccountJoinResponse response = tenantAccountJoinService.update(id, request);
            logger.info("更新租户账号关联成功: joinId={}", id);
            return ResponseResult.success(response);
        } catch (RuntimeException e) {
            logger.error("更新租户账号关联失败: joinId={}, error={}", id, e.getMessage());
            return ResponseResult.error(404, e.getMessage());
        } catch (Exception e) {
            logger.error("更新租户账号关联失败: {}", e.getMessage(), e);
            return ResponseResult.error(500, "更新失败: " + e.getMessage());
        }
    }
    
    /**
     * 删除租户账号关联
     */
    @DeleteMapping("/{id}")
    @Operation(summary = "删除租户账号关联", description = "移除账号与租户的关联")
    public ResponseResult<Void> delete(
            @Parameter(description = "关联ID") @PathVariable Long id) {
        try {
            tenantAccountJoinService.delete(id);
            logger.info("删除租户账号关联成功: joinId={}", id);
            return ResponseResult.success(null);
        } catch (RuntimeException e) {
            logger.error("删除租户账号关联失败: joinId={}, error={}", id, e.getMessage());
            return ResponseResult.error(404, e.getMessage());
        } catch (Exception e) {
            logger.error("删除租户账号关联失败: {}", e.getMessage(), e);
            return ResponseResult.error(500, "删除失败: " + e.getMessage());
        }
    }
    
    /**
     * 获取租户账号关联详情
     */
    @GetMapping("/{id}")
    @Operation(summary = "获取租户账号关联详情", description = "根据ID获取关联详细信息")
    public ResponseResult<TenantAccountJoinResponse> detail(
            @Parameter(description = "关联ID") @PathVariable Long id) {
        try {
            TenantAccountJoinResponse response = tenantAccountJoinService.getById(id);
            return ResponseResult.success(response);
        } catch (RuntimeException e) {
            logger.error("查询租户账号关联失败: joinId={}, error={}", id, e.getMessage());
            return ResponseResult.error(404, "关联不存在");
        } catch (Exception e) {
            logger.error("查询租户账号关联失败: {}", e.getMessage(), e);
            return ResponseResult.error(500, "查询失败: " + e.getMessage());
        }
    }
    
    /**
     * 获取租户账号关联列表（分页）
     */
    @GetMapping
    @Operation(summary = "获取租户账号关联列表", description = "分页查询关联列表，支持多条件过滤")
    public ResponseResult<PageResponse<TenantAccountJoinResponse>> list(
            @Parameter(description = "租户ID") @RequestParam(required = false) Long tenantId,
            @Parameter(description = "账号ID") @RequestParam(required = false) Long accountId,
            @Parameter(description = "角色ID") @RequestParam(required = false) Long roleId,
            @Parameter(description = "页码") @RequestParam(required = false, defaultValue = "1") Integer page,
            @Parameter(description = "每页大小") @RequestParam(required = false, defaultValue = "10") Integer pageSize) {
        try {
            TenantAccountJoinListRequest request = new TenantAccountJoinListRequest();
            request.setTenantId(tenantId);
            request.setAccountId(accountId);
            request.setRoleId(roleId);
            request.setPage(page);
            request.setPageSize(pageSize);
            
            PageResponse<TenantAccountJoinResponse> response = tenantAccountJoinService.list(request);
            logger.info("租户账号关联列表查询成功: page={}, pageSize={}, total={}", page, pageSize, response.getTotal());
            
            return ResponseResult.success(response);
        } catch (Exception e) {
            logger.error("租户账号关联列表查询失败: {}", e.getMessage(), e);
            return ResponseResult.error(500, "查询失败: " + e.getMessage());
        }
    }
    
    /**
     * 获取租户的账号列表
     */
    @GetMapping("/tenant/{tenantId}/accounts")
    @Operation(summary = "获取租户的账号列表", description = "查询指定租户下的所有账号及其角色")
    public ResponseResult<TenantWithAccountsResponse> tenantAccounts(
            @Parameter(description = "租户ID") @PathVariable Long tenantId) {
        try {
            TenantWithAccountsResponse response = tenantAccountJoinService.getTenantAccounts(tenantId);
            logger.info("查询租户账号列表成功: tenantId={}, accountCount={}", tenantId, response.getAccountCount());
            return ResponseResult.success(response);
        } catch (RuntimeException e) {
            logger.error("查询租户账号列表失败: tenantId={}, error={}", tenantId, e.getMessage());
            return ResponseResult.error(404, e.getMessage());
        } catch (Exception e) {
            logger.error("查询租户账号列表失败: {}", e.getMessage(), e);
            return ResponseResult.error(500, "查询失败: " + e.getMessage());
        }
    }
    
    /**
     * 获取账号所属的租户列表
     */
    @GetMapping("/account/{accountId}/tenants")
    @Operation(summary = "获取账号所属的租户列表", description = "查询指定账号所属的所有租户及其角色")
    public ResponseResult<AccountWithTenantsResponse> accountTenants(
            @Parameter(description = "账号ID") @PathVariable Long accountId) {
        try {
            AccountWithTenantsResponse response = tenantAccountJoinService.getAccountTenants(accountId);
            logger.info("查询账号租户列表成功: accountId={}, tenantCount={}", accountId, response.getTenantCount());
            return ResponseResult.success(response);
        } catch (RuntimeException e) {
            logger.error("查询账号租户列表失败: accountId={}, error={}", accountId, e.getMessage());
            return ResponseResult.error(404, e.getMessage());
        } catch (Exception e) {
            logger.error("查询账号租户列表失败: {}", e.getMessage(), e);
            return ResponseResult.error(500, "查询失败: " + e.getMessage());
        }
    }
    
    /**
     * 获取租户账号角色信息
     */
    @GetMapping("/tenant/{tenantId}/account/{accountId}/role")
    @Operation(summary = "获取租户账号角色信息", description = "查询指定租户和账号的角色关联信息")
    public ResponseResult<TenantAccountJoinResponse> tenantAccountRole(
            @Parameter(description = "租户ID") @PathVariable Long tenantId,
            @Parameter(description = "账号ID") @PathVariable Long accountId) {
        try {
            TenantAccountJoinResponse response = tenantAccountJoinService.getTenantAccountRole(tenantId, accountId);
            return ResponseResult.success(response);
        } catch (RuntimeException e) {
            logger.error("查询租户账号角色失败: tenantId={}, accountId={}, error={}", 
                        tenantId, accountId, e.getMessage());
            return ResponseResult.error(404, "关联不存在");
        } catch (Exception e) {
            logger.error("查询租户账号角色失败: {}", e.getMessage(), e);
            return ResponseResult.error(500, "查询失败: " + e.getMessage());
        }
    }
}

